﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Forest.Lion.Domain.Contracts;
using Microsoft.Practices.ServiceLocation;
using Forest.Lion.Web.Models.JobPosition;
using Forest.Lion.Domain.Shared;
using Forest.Lion.Domain.Services;
using System.Text.RegularExpressions;
using Forest.Lion.Model;
using Forest.Lion.Web.Framework.Controllers;
using Forest.Lion.Web.Models;
using Forest.Lion.Infrastructure;

namespace Forest.Lion.Web.Controllers
{
    public class JobPositionController : AuthorizedController
    {
        #region Const
        private const int _pageSize = 15;
        private const String _dateFormat = "yyyy/MM/dd";
        private const String _dateFormatTime = "yyyy/MM/dd HH:mm:ss";
        private const String _defaultKeyword = "关键字过滤";
        #endregion

        //
        // GET: /JobPosition/
        public JobPositionController(IUserServices userServices,
            IServiceLocator serviceLocator)
            : base(userServices, serviceLocator)
        {
        }

        public ActionResult Index()
        {
            return View();
        }

        #region List
        public ActionResult List(PagingFilteringModel command,
            JobQueryStatus jobQueryStatus = JobQueryStatus.All,
            String keyword = "")
        {
            //初始化分页组件
            if (command.PageSize <= 0) command.PageSize = _pageSize;
            if (command.PageNumber <= 0) command.PageNumber = 1;
            //如果关键字等于默认关键字则置空
            if (keyword.Equals(_defaultKeyword)) keyword = String.Empty;
            //取得分页数据
            var pagedList = Using<JobPosiotionAppService>().SearchList(this.CurrentUserId, jobQueryStatus, keyword, command.PageIndex, command.PageSize);
            var model = new JobPositionListViewModel()
            {
                PagingFilteringContext = new PagingFilteringModel(),
            };
            model.PagingFilteringContext.LoadPagedList(pagedList);
            //转换成ViewModel
            var list = pagedList.ToList().Select(x => new JobPositionListItemModel()
            {
                ItemChecked = false,
                DepartmentName = x.Department != null ? x.Department.DepartmentName : String.Empty,
                EndDate = x.EndDate.ToString(_dateFormat),
                Id = x.Id,
                JobTitle = x.JobTitle,
                Reposted = x.Reposted.HasValue ? x.Reposted.Value.ToString(_dateFormat) : String.Empty,
                Status = x.Status,
                Deleted = x.Deleted,
                Address = x.Address,
                SortOrder = x.SortOrder,
                StartDate = x.StartDate.HasValue ? x.StartDate.Value.ToString(_dateFormat) : String.Empty,
                DateCreated = x.DateCreated.ToString(_dateFormatTime),
                DateDeleted = x.LastUpdated.ToString(_dateFormatTime),
            });
            model.JobPositionList = list;
            model.Keyword = keyword;
            model.JobQueryStatus = jobQueryStatus;
            ViewBag.DefaultKeyword = _defaultKeyword;
            return View(model);
        }

        #region Delete
        [HttpPost]
        [ActionName("List")]
        [FormValueRequired("Delete")]
        public ActionResult Delete(Guid id, JobPositionListViewModel model)
        {
            return Excute(id, model, Using<JobPosiotionAppService>().Delete);
        }

        [HttpPost]
        [ActionName("List")]
        [FormValueRequired("DeleteSelected")]
        public ActionResult DeleteSelected(JobPositionListViewModel model)
        {
            return ExcuteSelected(model, Using<JobPosiotionAppService>().Delete);
        }
        #endregion

        #region Post
        [HttpPost]
        [ActionName("List")]
        [FormValueRequired("Post")]
        public ActionResult Post(Guid id, JobPositionListViewModel model)
        {
            return Excute(id, model, Using<JobPosiotionAppService>().Post);
        }

        [HttpPost]
        [ActionName("List")]
        [FormValueRequired("PostSelected")]
        public ActionResult PostSelected(JobPositionListViewModel model)
        {
            return ExcuteSelected(model, Using<JobPosiotionAppService>().Post);
        }
        #endregion

        #region Restore
        [HttpPost]
        [ActionName("List")]
        [FormValueRequired("Restore")]
        public ActionResult Restore(Guid id, JobPositionListViewModel model)
        {
            return Excute(id, model, Using<JobPosiotionAppService>().Restore);
        }

        [HttpPost]
        [ActionName("List")]
        [FormValueRequired("RestoreSelected")]
        public ActionResult RestoreSelected(JobPositionListViewModel model)
        {
            return ExcuteSelected(model, Using<JobPosiotionAppService>().Restore);
        }
        #endregion

        #region Pause
        [HttpPost]
        [ActionName("List")]
        [FormValueRequired("Pause")]
        public ActionResult Pause(Guid id, JobPositionListViewModel model)
        {
            return Excute(id, model, Using<JobPosiotionAppService>().Pause);
        }

        [HttpPost]
        [ActionName("List")]
        [FormValueRequired("PauseSelected")]
        public ActionResult PauseSelected(JobPositionListViewModel model)
        {
            return ExcuteSelected(model, Using<JobPosiotionAppService>().Pause);
        }
        #endregion

        #region Refresh
        [HttpPost]
        [ActionName("List")]
        [FormValueRequired("Refresh")]
        public ActionResult Refresh(Guid id, JobPositionListViewModel model)
        {
            return Excute(id, model, Using<JobPosiotionAppService>().Refresh);
        }

        [HttpPost]
        [ActionName("List")]
        [FormValueRequired("RefreshSelected")]
        public ActionResult RefreshSelected(JobPositionListViewModel model)
        {
            return ExcuteSelected(model, Using<JobPosiotionAppService>().Refresh);
        }
        #endregion

        #region 执行
        private ActionResult Excute(Guid id, JobPositionListViewModel model, Action<Guid> action)
        {
            action(id);
            return RedirectToAction("List", new { jobQueryStatus = model.JobQueryStatus, keyword = model.Keyword });
        }

        private ActionResult ExcuteSelected(JobPositionListViewModel model, Action<Guid> action)
        {
            foreach (var item in model.JobPositionList.Where(x => x.ItemChecked))
            {
                action(item.Id);
            }
            return RedirectToAction("List", new { jobQueryStatus = model.JobQueryStatus, keyword = model.Keyword });
        }
        #endregion

        #region ChangeSortOrder
        [HttpPost]
        public void ChangeSortOrder(Guid id, int sortOrder)
        {
            Using<JobPosiotionAppService>().ChangeSortOrder(id, sortOrder);
        } 
        #endregion

        #endregion

        #region Add
        public ActionResult Add()
        {
            var company = Using<CompanyAppService>().GetById(this.CurrentUserId);
            var model = new JobPositionFormModel()
            {
                Fax = company.Fax,
                Address = company.Address,
                Tel = company.Tel,
                Email = company.Email,
                PostalCode = company.PostalCode,
                Contact = company.Contact,
                UseDepartmentAddress = false,
                IsReceivedEmail = true,
                RecruiteGraduates = true,
                JobType = 105102,//正式
                EducationLevel = 106108,//本科
                Status = (int)JobQueryStatus.New,
                Location = 1283607,//高新区
                DateRage = 30,//默认选中30天
            };
            PrepareRelatedDataForJobPositionFormModel(model);
            return View(model);
        }

        [Authorize]
        [ActionName("Add")]
        [FormValueRequired("SaveInfo")]
        [HttpPost]
        public ActionResult Add(JobPositionFormModel model)
        {
            if (IsValid(model))
            {
                model.StartDate = DateTime.Now.Date;
                model.EndDate = DateTime.Now.AddDays(model.DateRage).Date;
                model.Reposted = DateTime.Now;
                Using<JobPosiotionAppService>().Create(model, this.CurrentUserId);
                return RedirectToAction("List");
            }
            PrepareRelatedDataForJobPositionFormModel(model);
            return View(model);
        }

        [Authorize]
        [ActionName("Add")]
        [FormValueRequired("Post")]
        [HttpPost]
        public ActionResult AddPost(JobPositionFormModel model)
        {
            if (IsValid(model))
            {
                model.Status = (int)JobQueryStatus.Active;
                model.StartDate = DateTime.Now.Date;
                model.EndDate = DateTime.Now.AddDays(model.DateRage).Date;
                Using<JobPosiotionAppService>().Create(model, this.CurrentUserId);
            }
            PrepareRelatedDataForJobPositionFormModel(model);
            return View(model);
        }

        #endregion

        #region Edit
        public ActionResult Edit(Guid id)
        {
            var entity = Using<JobPosiotionAppService>().GetById(id);
            var model = PrepareJobPositionFormModel(entity);
            if (model.Status != (int)JobPositionStatus.Active)
            {
                model.DateRage = new TimeSpan(entity.EndDate.Ticks - entity.StartDate.Value.Ticks).Days;
            }
            else
            {
                model.EndDateDisplay = entity.EndDate.ToString(_dateFormat);
            }
            PrepareRelatedDataForJobPositionFormModel(model);
            return View(model);
        }

        [Authorize]
        [ActionName("Edit")]
        [FormValueRequired("SaveInfo")]
        [HttpPost]
        public ActionResult Edit(JobPositionFormModel model)
        {
            if (IsValid(model))
            {
                if (model.Status != (int)JobPositionStatus.Active)
                {
                    model.StartDate = DateTime.Now.Date;
                    model.EndDate = DateTime.Now.AddDays(model.DateRage).Date;
                }
                Using<JobPosiotionAppService>().Update(model);
                return RedirectToAction("List");
            }
            PrepareRelatedDataForJobPositionFormModel(model);
            return View(model);
        }

        [Authorize]
        [ActionName("Edit")]
        [FormValueRequired("Post")]
        [HttpPost]
        public ActionResult EditPost(JobPositionFormModel model)
        {
            if (IsValid(model))
            {
                model.Status = (int)JobQueryStatus.Active;
                model.StartDate = DateTime.Now.Date;
                model.EndDate = DateTime.Now.AddDays(model.DateRage).Date;
                model.Reposted = DateTime.Now;
                Using<JobPosiotionAppService>().Update(model);
            }
            PrepareRelatedDataForJobPositionFormModel(model);
            return View(model);
        }

        #endregion

        #region Other
        private JobPositionFormModel PrepareJobPositionFormModel(JobPosition entity)
        {
            return new JobPositionFormModel
            {
                Id = entity.Id,
                JobTitle = entity.JobTitle,
                Category = entity.Category,
                JobType = entity.JobType,
                DepartmentId = entity.DepartmentId,
                UseDepartmentAddress = entity.UseDepartmentAddress.Value,
                Wants = entity.Wants,
                Location = entity.Location,
                Responsibilities = entity.Responsibilities,
                Major = entity.Major,
                EducationLevel = entity.EducationLevel,
                YearsOfExperience = entity.YearsOfExperience,
                Language = entity.Language,
                LanguageLevel = entity.LanguageLevel,
                MinAge = entity.MinAge,
                MaxAge = entity.MaxAge,
                Qualifications = entity.Qualifications,
                SalaryRange = entity.SalaryRange,
                MonthlySalary = entity.MonthlySalary,
                IsOpenSalaryRange = entity.IsOpenSalaryRange,
                Welfare = entity.Welfare,
                Contact = entity.Contact,
                Email = entity.Email,
                Tel = entity.Tel,
                Fax = entity.Fax,
                Address = entity.Address,
                PostalCode = entity.PostalCode,
                SortOrder = entity.SortOrder,
                RecruiteGraduates = entity.RecruiteGraduates.Value,
                IsReceivedEmail = entity.IsReceivedEmail.Value,
                Status = entity.Status,
            };
        }

        /// <summary>
        /// 为显示模型附加上相关数据
        /// </summary>
        /// <param name="model"></param>
        private void PrepareRelatedDataForJobPositionFormModel(JobPositionFormModel model)
        {
            model.CategoryList = Using<LovHandler>().GetListByParentId(GetLovId(LovType.JobCategory));
            model.SubCategoryList = Using<LovHandler>().GetSubListByParentId(GetLovId(LovType.JobCategory));
            model.LocationList = Using<LovHandler>().GetListByParentId(GetLovId(LovType.Regionalism));
            model.SubLocationList = Using<LovHandler>().GetSubListByParentId(GetLovId(LovType.Regionalism));
            model.JobTypeList = Using<LovHandler>().GetListByParentId(GetLovId(LovType.JobType));
            model.EducationLevelList = DropDownListHelper(LovType.EducationLevel);
            model.LanguageLevelList = DropDownListHelper(LovType.Level);
            model.LanguageList = DropDownListHelper(LovType.Language);
            model.SalaryRangeList = DropDownListHelper(LovType.SalaryRange);
            model.YearsOfExperienceList = DropDownListHelper(LovType.YearsOfExperience);
            model.MajorList = DropDownListHelper(LovType.Major);
            model.DepartmentList = Using<DepartmentHandler>().GetDeparmentsForCompany(this.CurrentUserId).Select(x => new DepartmentFormModel()
            {
                Contact = x.Contact,
                DepartmentName = x.DepartmentName,
                Email = x.Email,
                Fax = x.Fax,
                Id = x.Id,
                Mobile = x.Mobile,
                Tel = x.Tel
            });
            //model.DepartmentList = Using<DepartmentHandler>().GetDeparmentsForCompany(this.CurrentUserId).Select(x => new SelectListItem()
            //{
            //    Text = x.DepartmentName,
            //    Value = x.Id.ToString()
            //});

            //年龄
            var ageList = new List<SelectListItem>();
            for (var i = 18; i < 60; i++)
            {
                ageList.Add(new SelectListItem() { Text = i.ToString(), Value = i.ToString() });
            }
            ageList.Insert(0, new SelectListItem() { Text = "请选择", Value = "" });
            model.AgeList = ageList;
            //职位时效范围
            model.GenderList = Using<LovHandler>().GetListByParentId(GetLovId(LovType.Gender));
            model.DateRageList = new List<SelectListItem>()
            {
                new SelectListItem(){Text = "一个月(30日)", Value="30"  },
                new SelectListItem(){Text = "半个月(15日)", Value="15"  },
                new SelectListItem(){Text = "一周(7日)", Value="7"  },
            };
            ViewBag.IsVip = this.CurrentUser.IsVip;
        }

        private Guid GetLovId(LovType lovType)
        {
            var lovTypeValue = ((int)lovType).ToString();
            return GetLovId(lovTypeValue);
        }

        private Guid GetLovId(String lovTypeValue)
        {
            //格式化：例如 201000 格式化成 00000000-0000-0000-0000-000000201000 的形式
            var regex = new Regex(@"\d{" + lovTypeValue.Length + "}$");
            var id = Guid.Parse(regex.Replace(Guid.Empty.ToString(), lovTypeValue));
            return id;
        }

        private IEnumerable<SelectListItem> DropDownListHelper(LovType type)
        {
            return Using<LovHandler>().GetListByParentId(GetLovId(type)).
                Select(x => new SelectListItem()
            {
                Text = x.Name,
                Value = x.Value.Value.ToString()
            });
        }

        /// <summary>
        /// 判断薪水范围是否有效
        /// </summary>
        /// <param name="model"></param>
        private void CheckMonthlySalary(JobPositionFormModel model)
        {
            var lov = Using<LovHandler>().GetById(GetLovId(model.SalaryRange.ToString()));
            var salaryValue = lov.Label.Split('-');
            var min = String.IsNullOrWhiteSpace(salaryValue[0]) ? "0" : salaryValue[0];
            var max = String.IsNullOrWhiteSpace(salaryValue[1]) ? int.MaxValue.ToString() : salaryValue[1];
            if (model.MonthlySalary < int.Parse(min) || model.MonthlySalary > int.Parse(max))
            {
                //ModelState.AddModelError("MonthlySalaryRangeError", "月薪范围必须在" + lov.Name);
                ModelState.AddModelError("MonthlySalary", "月薪范围必须在" + lov.Name);
            }
        }

        private bool IsValid(JobPositionFormModel model)
        {
            CheckMonthlySalary(model);
            if (ModelState.IsValid)
            {
                return true;
            }
            else
            {
                if (ModelState["Category"].Errors.Any())
                {
                    ViewBag.CategoryError = true;
                }
                if (ModelState["Location"].Errors.Any())
                {
                    ViewBag.LocationError = true;
                }
            }
            return false;
        }

        #endregion
    }
}
